<?php

require_once($_SERVER['DOCUMENT_ROOT']."/classes/System/osfield.php");
require_once("iobserver.php");
require_once($_SERVER['DOCUMENT_ROOT']."/classes/System/osmetafield.php");

class osentity implements iobserver {
	
	protected $state; // State i.e. edit, insert, ready
	protected $items = array(); // List of items current view
	protected $select; // Selected item No
	protected $offset = 0; // Offset of table items
	protected $limit = 5; // Limit. Count items viewed 
	protected $sortby = "id"; // Sorting by field
	protected $direction = "ASC"; // Direction of sorting
	private $fields = array(); // List of fields
	//private $tabulars = array(); // List of tabulars
	//public $uuid;
	public $owner = null;
	
	function open() {
		//unset($this->item);
		$this->update();
	}
	
	function addfield($field = null) {
		if (!$field) {
			$field = new osfield();
		}
		$field->addObserver($this,1);
		$this->fields[] = $field;
		return $field;
	}
	
	function fieldbyname($name){
		foreach ($this->fields as $field) {
			if ($name == $field->meta->name) {
				return $field;
			}
		}
	}
	
	function getfields() {
		return $this->fields;
	}
	
	function observable_before_changed($sender, &$value) {
		foreach ($this->fields as $field) {
			${$field->meta->name} = $field;
		}
		eval($sender->meta->beforechange);
	}
	
	function observable_after_changed($sender, &$value) {
		foreach ($this->fields as $field) {
			${$field->meta->name} = $field;
		}
		eval($sender->meta->afterchange);
	}
	
	function update() {
		$sql = "SELECT * FROM ".$this->meta->uuid;
		$sql .= $this->owner ? " WHERE owner = '".$this->owner."'" : "";
		$sql .= " ORDER BY ".$this->sortby." ".$this->direction;
		$sql .= " LIMIT ".$this->limit." OFFSET ".$this->offset;
		$sql .= ";";
		//echo $sql;
		$this->items = $_SESSION["metadata"]->database->select($sql);
		$this->select = key($this->items);
	}
	
	function __get($name) {
		switch ($name) {
			case "select": {return $this->select; break;}
			case "offset": { return $this->offset;break;}
			case "limit": { return $this->limit;break;}
			case "sortby": { return $this->sortby;break;}
			case "direction": { return $this->direction;break;}
		}
	}
	
	function getitems() {
		return $this->items;
	}
	
	function __set($name, $value) {
		switch ($name) {
			case "select": {$this->select = $value; $this->assignfield();break;}
			case "offset": {$this->offset = $value; $this->update();break;}
			case "limit": {$this->limit = $value; $this->update();break;}
			case "sortby": {$this->sortby = $value; $this->update();break;}
			case "direction": {$this->direction = $value; $this->update();break;}
		}
	}
	
	function assignfield() {
		foreach ($this->fields as $field) {
			$field->value = $this->items[$this->select][$field->uuid];
		}
	}
	
	function add() {
		$this->state = "isadd";
		//eval($this->onadd);
		//$this->select = genUUID();
		foreach ($this->fields as $field) {
			$field->value = $field->meta->defaultvalue;
		}
	}
	
	function edit() {
		$this->state = "isedit";
	}
	
	function save() {
		if ($this->state == "isedit") {
			$action = "UPDATE ".$this->meta->uuid." SET";
			foreach ($this->fields as $field) {
				$action .= " ". $field->meta->uuid ." = '".addslashes($field->value)."',";
			}
			$action = substr_replace($action, "", -1, 1);
			$action .= " WHERE (id = '".$this->items[$this->select]["id"]."')";
			$action .= $this->owner ? " AND (owner = '".$this->owner."')" : "";
			$action .= ";";
			$_SESSION["metadata"]->database->query($action);
		} elseif ($this->state == "isadd") {
			$action = "INSERT INTO ".$this->meta->uuid."(";
			$action .= " id, ";
			foreach ($this->fields as $field) {
				$action .=  " ". $field->meta->uuid.",";
			}
			$action = substr_replace($action, ")", -1, 1);
			$action .= " VALUES(";
			$action .= " 'genUUID()',";
			foreach ($this->fields as $field) {
				$action .= " '".addslashes($field->value)."',";
			}
			$action = substr_replace($action, ");", -1, 1);
			$_SESSION["metadata"]->database->query($action);
		} else {}
		//echo $action;
		$this->state = "isready";
		$this->update();
	}
	
	function cancel() {
		$this->state = "iscancel";
		$this->assignfield();
	}
}
?>

